<script setup lang="ts">
import { h, onMounted, onBeforeUpdate, onUnmounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { NFlex, NCard, NDropdown, NButton, NTag, NTabs, NTabPane, NIcon, NButtonGroup, NColorPicker, NSpace, NInput, NCountdown, type CountdownInst } from 'naive-ui';
import SvgIcon from '../components/SvgIcon.vue';
import { HyperFormula } from 'hyperformula';
import * as echarts from 'echarts'
import { createDiscreteApi } from "naive-ui";
const { message } = createDiscreteApi(["message"])
import { FORM_ADD } from "@/service/apis/from";


const router = useRouter()

interface App {
  名称: string
  缩写: string
  路由?: string
  图标?: string
  类型?: string
}
/**
 * 使用组件传值的方式，将组件的标题头和图标传进来
 */
//接收props
const props = defineProps({
    title: {
        type: String,
        default: '在线excel协同' // 默认值
    },
    icon: {
        type: String,
        default: 'excel1' // 默认值
    },
    fileData: {
        type: Array,
        default: undefined // 默认值
    },
    mode: {
        type: String,
        default: 'create' // 默认值
    },
    currentApp: {
        type: Object as () => App,
        default: {}// 默认值
    },
    editFileName: {
        type: String,
        default: undefined // 默认值
    },
})
const AUTO_SAVE_TIME = 60 * 1000; // 自动保存时间 ms
let editFileNameMode = ref(false);
const countdownRef = ref<CountdownInst | null>()
let inputFileName = ref(props.editFileName);
let saveMode = props.editFileName ? "cover" : "new-create";
let oneMinInterval;
let autoSaveHappened = ref(false)
const startInterval = () => {
  oneMinInterval = setInterval(() => {
    console.log('1min-save 定时 保存')
    saveExcel();
    autoSaveHappened.value = true; // 发生过自动保存
    countdownRef.value?.reset() // 重置倒计时
    saveMode = 'cover' // 后续保存都为覆盖模式
  }, AUTO_SAVE_TIME);
}


const killInterval = () => {
  clearInterval(oneMinInterval!);
};

onUnmounted(() => {
  killInterval();
});

/**
 * 右侧面板，对单元格式设置
 */
const rightPlane = ref(true) // 右侧面板是否显示

const showPlane = () => {
    if (rightPlane.value) {
        rightPlane.value = false;
    } else {
        rightPlane.value = true;
    }
};


/**
 * 这是excel 组件
 */
import { HotTable } from '@handsontable/vue3'
import { registerAllModules } from 'handsontable/registry';
import { registerLanguageDictionary, zhCN } from 'handsontable/i18n'
import 'handsontable/dist/handsontable.full.css'
// 注册语言字典
registerLanguageDictionary(zhCN)
// register Handsontable's modules
registerAllModules();
/**
 * 定义ref对象，获取handsontable组件对象
 * 这里是vue3的组件对象获取方式
 * handsontable 有两种使用方式，一是vue3 组件，二是API对象引用方式
 */
import type { BaseRenderer } from 'handsontable/renderers';
import { encodeString } from '@/assets/utils/charEncoder';
/**
 * 定义ref对象，获取hottable组件对象
 * 默认支持三个sheet
 */
let selected: any;

//定义一个变量，获取当前tabs的切换那个sheet的code
const sheetCode = ref<string>('sheet1') // 当前sheet的code 为sheet1

/**
 * 定义api对象，获取handsontable组件对象
 */
// let handsontable = ref<Handsontable | any>(null)
/**
 * end
 */

/**
 * 声明excel相关的变量
 * 定义单元格的可读性
 * 定义单元格的列数据类型
 * 定义单元格数组
 */
// 定义只读的单元格数组
const readOnlyCells = [
    { row: 0, col: 1, readOnly: true }, // 第一行第二列为只读
    { row: 1, col: 1, readOnly: true }  // 第二行第二列为只读
];

/**
 * 定义单元格列的数据类型
 */
//  const columstype = [
//     { col: 1, type: 'password' }, // 第一列为数字类型
//     { col: 2, type: 'numeric' }, // 第二列为数字类型
//     { col: 3, type: 'date' }, // 第三列为数字类型
//     { col: 4, type: 'dropdown', source: ['A', 'B', 'C'] }, // 第四列为下拉框类型
//     { col: 5, type: 'checkbox' }, // 第五列为复选框类型
//     { col: 6, type: 'autocomplete', source: ['A', 'B', 'C'] } // 第六列为自动完成类型
// ];

const columstype = [
    { col: 1 },
    { col: 2 },
    { col: 3 },
    { col: 4 },
    { col: 5 },
    { col: 6 }
];

/**
 * 定义数据接口
 */
interface Excedata {
    data: (string | number | any)[][]
}

// let exceldata: Excedata = reactive({ data: [[, , , , ,], [, , , , ,], [, , , , ,], [, , , , ,], [, , , , ,], [, , , , ,]] })

/**
 * 声明excel相关的变量
 * end
 */
/**
 * 定义sheet表格，HotTable 组件ref数组对象定义
 */
interface HotTableRef {
    key: string;
    setting: string | any;
    echarts: string;
    data: Excedata | any;
}
type SheetRefsType = {
    [key: string]: any;
}
const sheetListRefs = reactive<SheetRefsType>({})
const hotTableList = reactive<HotTableRef[] | any>([])
/**
 * 自定义单元格渲染方法，用于设置字色背景色等
 * 文档参见
 * https://handsontable.com/docs/javascript-data-grid/vue3-custom-renderer-example/#related-guides
 */
const cellStyleRenderer: BaseRenderer = (
    instance,
    td,
    row,
    col,
    prop,
    value,
    cellProperties,
) => {
    const table = hotTableList.filter((item: any) => item.key === sheetCode.value)[0]
    const { customStyle } = table

    if (customStyle) {
        const style = customStyle[`${row}-${col}`] || {}
        td.style.background = style.background
        td.style.color = style.color
    }

    td.innerText = value
    td.className = cellProperties.className?.toString() || ''
    return td
};


/**
  * 设置成中文支持
  * 注册为开源应用
  * 开启上下文菜单功能
  */
const excelSettings = ref(
    {
        licenseKey: 'non-commercial-and-evaluation',
        // data: exceldata.data, // 绑定数据
        // columns: columstype, // 绑定列类型
        // cell: readOnlyCells, // 绑定只读单元格
        formulas: {
            engine: HyperFormula,
        }, // 公式支持
        contextMenu: true,
        language: 'zh-CN',
        // width: '100%',
        height: 'auto',
        rowHeights: 40,
        colWidths: 150,
        rowHeaders: true,
        colHeaders: true,
        filters: true,
        dropdownMenu: true,
        manualRowMove: true,
        // colWidths: 300,
        manualColumnResize: true, // 支持手动调节列宽
        manualRowResize: true, // 支持手动调节行高
        autoWrapRow: true,
        autoWrapCol: true,
        // cells: customCellRender,
        renderer: cellStyleRenderer,
        // mergeCells: true,
        // startRows: 10,
        // startCols:10,
        // readOnly: true,
        // stretchH: 'all'
    })
/**
 * end
 */

let excelTableLoading = ref(false)
 onBeforeUpdate(() => {
    excelTableLoading.value = true
    if (props.mode==='update' && props.fileData && props.fileData.length > 0) {
        console.log('加载传入属性数据', [...props.fileData], hotTableList)
        hotTableList.splice(0, hotTableList.length); 
        props.fileData.forEach((item: any, index) => {
            item.setting.formulas = {engine: HyperFormula}
            hotTableList.push(item)
            // item.data.forEach((row: any, rowIndex: number) => {
            //     row.forEach((cell: any, cellIndex: number) => {
            //         sheetListRefs[sheetCode.value].hotInstance.setDataAtCell(rowIndex, cellIndex, cell)
            //     })
            // })
        })

        if (sheetListRefs[sheetCode.value]){
            console.log('更新数据', sheetListRefs[sheetCode.value].hotInstance)
            sheetListRefs[sheetCode.value].hotInstance.render();
        }
    } 
    setTimeout(() => {
        excelTableLoading.value = false
    }, 50)

    // else {
    //     console.log('预置配置数据')
    //     hotTableList.push({ key: 'sheet1', setting: { ...excelSettings.value }, customStyle: {}, echarts: 'echarts1', showEcharts: false, echartsOption: {}, data: [["", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""], ["", "", "", ""]] })
    //     hotTableList.push({ key: 'sheet2', setting: { ...excelSettings.value }, customStyle: {}, echarts: 'echarts2', showEcharts: false, echartsOption: {}, data: [["", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""], ["", "", "", ""]] })
    //     hotTableList.push({ key: 'sheet3', setting: { ...excelSettings.value }, customStyle: {}, echarts: 'echarts3', showEcharts: false, echartsOption: {}, data: [["", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""], ["", "", "", ""]] })
    //     hotTableList.push({ key: 'sheet4', setting: { ...excelSettings.value }, customStyle: {}, echarts: 'echarts4', showEcharts: false, echartsOption: {}, data: [["", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""], ["", "", "", ""]] })
    // }

})

/**
 * 监听单元格选择  
 * 监听默认的单元格选择事件，获取选中的单元格坐标
 */
const scol = () => {
    setTimeout(() => {
        sheetListRefs[sheetCode.value].hotInstance.addHook('afterSelectionEnd', () => {
            selected = sheetListRefs[sheetCode.value].hotInstance.getSelected()
            console.log('选中行列', selected)
        })
    }, 200)
}
onMounted(() => {
    // initialize()
    console.log('初始化数据', props)
    // if (props.fileData && props.fileData.length > 0) {
    //     console.log('加载传入属性数据', [...props.fileData])
    //     hotTableList.value = []
    //     hotTableList.push(...props.fileData)
    // } 
    if (props.mode==='create' && !props.fileData) {
        console.log('预置配置数据')
        hotTableList.push({ key: 'sheet1', setting: { ...excelSettings.value }, customStyle: {}, echarts: 'echarts1', showEcharts: false, echartsOption: {}, data: [["", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""], ["", "", "", ""]] })
        hotTableList.push({ key: 'sheet2', setting: { ...excelSettings.value }, customStyle: {}, echarts: 'echarts2', showEcharts: false, echartsOption: {}, data: [["", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""], ["", "", "", ""]] })
        hotTableList.push({ key: 'sheet3', setting: { ...excelSettings.value }, customStyle: {}, echarts: 'echarts3', showEcharts: false, echartsOption: {}, data: [["", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""], ["", "", "", ""]] })
        hotTableList.push({ key: 'sheet4', setting: { ...excelSettings.value }, customStyle: {}, echarts: 'echarts4', showEcharts: false, echartsOption: {}, data: [["", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""], ["", "", "", ""]] })
    }

    scol()

    startInterval();
})


const setItemRef = (key: string) => (el: any) => {
    sheetListRefs[key] = el
}
/**
* tab切换事件
* 切换sheet时，给 sheetCode 变量赋值
*/
const handleTabChange = (value: string) => {
    //注意 此处只为切换变量赋值，不允许做其它的操作
    sheetCode.value = value
    console.log('切换sheet:', value)

    // 切换标签页后，对应的hotInstance会初始化，因此需要重新增加hook，监听点击
    // echarts也会初始化，因此重新生成并挂载
    selected = undefined
    setTimeout(() => {
        sheetListRefs[value].hotInstance.addHook('afterSelectionEnd', () => {
            selected = sheetListRefs[value].hotInstance.getSelected()
            console.log('选中行列', selected)
        })

        const table = hotTableList.filter((item: any) => item.key === value)[0]
        const eDomId = table.echarts;

        const chart = echarts.init(document.getElementById(eDomId))
        chart.setOption(table.echartsOption)
    }, 100)
}


// 插入一行
/*
const inster = () => {
    console.log('插入一行')
    
        // table1.value.hotInstance.alter('insert_row_above', ff.value[0][0] + 1)
        sheetListRefs[sheetCode.value].hotInstance.addHook('afterSelectionEnd', () => {
            // table1.value.hotInstance.getSelected()
            const selected = sheetListRefs[sheetCode.value].hotInstance.getSelected()
            console.log('选中行列', selected)
        })
        sheetListRefs[sheetCode.value].hotInstance.alter('insert_row_above', 0)


    
    // if (ff.value !== undefined && ff.value !== null) {
    //     // handsontable.value.alter('insert_row_above', ff.value[0][0] + 1)
    // } else {
    //     // handsontable.value.alter('insert_row_above', 0)
    // }
    // hotTable.value.hotInstance.alter('insert_row_above', 0)
    // handsontable.value.alter('insert_row_above', 1)
    // insert_col_start

}
*/
const select = () => {
    // console.log('插入一列')
    // handsontable.value.selectCell(2,2)

    // handsontable.value.alter('insert_col_start', ff.value[0][1] + 1)

    // handsontable.value.alter('insert_col_start', 0)

    // hotTable.value.hotInstance.alter('insert_col_start', 0)
}

/**
 * 更新表格属性（非DATA），并重新触发界面渲染
 * @param sheetCodeValue 
 * @param newSettings 
 */
const updateTableSettings = (sheetCodeValue: string, newSettings: {}) => {
    const table = hotTableList.filter((item: any) => item.key === sheetCodeValue)[0]
    table.setting = { ...table.setting, ...newSettings }
    // 除了被动更新VUE变量，再用API主动设置一次属性，保障更新生效
    sheetListRefs[sheetCodeValue].hotInstance.updateSettings({ ...newSettings })
    sheetListRefs[sheetCode.value].hotInstance.render();
}

const readOnlyCellsClick = () => {
    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    // 对所有的选定格，都设置对应类型
    let cell = sheetListRefs[sheetCode.value].hotInstance.getSettings().cell
    for (let row = startRow; row <= endRow; row++) {
        for (let col = startCol; col <= endCol; col++) {
            cell = mergeCellSetting(cell, { row, col, readOnly: true });
        }
    }
    updateTableSettings(sheetCode.value, { cell })
}

const mergeCellsClick = () => {
    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    let oldMerged = sheetListRefs[sheetCode.value].hotInstance.getSettings().mergeCells
    if (!Array.isArray(oldMerged)) {
        oldMerged = []
    }

    const mergeCells = [...oldMerged,
    { row: startRow, col: startCol, rowspan: endRow - startRow + 1, colspan: endCol - startCol + 1 },
    ]

    updateTableSettings(sheetCode.value, { mergeCells })
    // sheetListRefs[sheetCode.value].hotInstance.updateSettings({ mergeCells })
}

const insertMenu = [
    { label: '上添加行', key: 'rowAbove' },
    { label: '下添加行', key: 'rowBelow' },
    { label: '左添加列', key: 'colLeft' },
    { label: '右添加列', key: 'colRight' },
]

/**
 * 
 * 插入：加行加列
 */
const insertMenuSelect = (key: string) => {
    console.log(selected)
    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    switch (key) {
        case 'rowAbove':
            sheetListRefs[sheetCode.value].hotInstance.alter('insert_row_above', startRow)
            break;
        case 'rowBelow':
            sheetListRefs[sheetCode.value].hotInstance.alter('insert_row_below', endRow)
            break;
        case 'colLeft':
            sheetListRefs[sheetCode.value].hotInstance.alter('insert_col_start', startCol)
            break;
        case 'colRight':
            sheetListRefs[sheetCode.value].hotInstance.alter('insert_col_end', endCol)
            break;

        default:
            break;
    }
    sheetListRefs[sheetCode.value].hotInstance.render();
}

const deleteMenu = [
    { label: '删除行', key: 'rowDel' },
    { label: '删除列', key: 'colDel' },
]

/**
 * 
 * 删除行列
 */
const deleteMenuSelect = (key: string) => {
    console.log(selected)
    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    switch (key) {
        case 'rowDel':
            for (let row = startRow; row <= endRow; row++) {
                sheetListRefs[sheetCode.value].hotInstance.alter('remove_row', startRow) // 删掉一行后，下面要删掉的行会上移，成为新的startRow 
            }
            break;
        case 'colDel':
            for (let col = startCol; col <= endCol; col++) {
                sheetListRefs[sheetCode.value].hotInstance.alter('remove_col', startCol) // 删掉一列后，后面要删掉的行会左移，成为新的startCol
            }
            break;

        default:
            break;
    }
    sheetListRefs[sheetCode.value].hotInstance.render();
}

const borderColorPicker = ref('#000000')
const editBorderColor = (color: string) => {
    borderColorPicker.value = color
    borderMenuSelect('外侧边框')
}
const borderMenu = [
    { label: '外侧边框', key: '外侧边框' },
    { label: '无边框', key: '无边框' },
]

/**
 * 
 * 边框
 */
const borderMenuSelect = (key: string, color?: string) => {
    console.log(selected)
    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    const range = {
        from: {
            row: startRow,
            col: startCol,
        },
        to: {
            row: endRow,
            col: endCol,
        },
    }

    const customBorder =
    {
        range,
        top: {
            width: 2,
            color: borderColorPicker.value,
        },
        bottom: {
            width: 2,
            color: borderColorPicker.value,
        },
        start: {
            width: 2,
            color: borderColorPicker.value,
        },
        end: {
            width: 2,
            color: borderColorPicker.value,
        },
    }

    const cancelBorder =
    {
        range,
        top: {
            width: 1,
            color: 'lightGray',
        },
        bottom: {
            width: 1,
            color: 'lightGray',
        },
        start: {
            width: 1,
            color: 'lightGray',
        },
        end: {
            width: 1,
            color: 'lightGray',
        },
    }

    let oldCustomBorders = sheetListRefs[sheetCode.value].hotInstance.getSettings().customBorders
    if (!oldCustomBorders) {
        oldCustomBorders = []
    }

    switch (key) {
        case '外侧边框':
            // sheetListRefs[sheetCode.value].hotInstance.updateSettings({ customBorders: [customBorder, ...oldCustomBorders] })
            updateTableSettings(sheetCode.value, { customBorders: [customBorder, ...oldCustomBorders] })
            break;
        case '无边框':
            // sheetListRefs[sheetCode.value].hotInstance.updateSettings({ customBorders: [cancelBorder, ...oldCustomBorders] })
            updateTableSettings(sheetCode.value, { customBorders: [cancelBorder, ...oldCustomBorders] })
            break;

        default:
            break;
    }
}

interface Cell {
    row: number;
    col: number;
    className?: string;
    type?: string;
    readOnly?: boolean
    backgroundColor?: any
}
const mergeCellSetting = (cell: Cell[], meta: Cell): Cell[] => {
    let updatedCell = [...cell]; // 创建一个副本以避免直接修改原数组  
    let found = false;

    for (let i = 0; i < updatedCell.length; i++) {
        if (updatedCell[i].row === meta.row && updatedCell[i].col === meta.col) {
            found = true;

            // 更新 className 和 type，如果它们被提供了  
            if (meta.className !== undefined) {
                updatedCell[i].className = meta.className;
            }
            if (meta.type !== undefined) {
                updatedCell[i].type = meta.type;
            }
            if (meta.readOnly) {
                updatedCell[i].readOnly = false
            }
        }
    }

    // 如果没有找到，则新增一个  
    if (!found) {
        updatedCell.push({ ...meta }); // 使用展开运算符确保只包含提供的属性  
    }

    return updatedCell;
}

const editTextColor = (color: string | null) => {
    console.log(color);

    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    const table = hotTableList.filter((item: any) => item.key === sheetCode.value)[0]

    for (let row = startRow; row <= endRow; row++) {
        for (let col = startCol; col <= endCol; col++) {
            table.customStyle[`${row}-${col}`] = { ...table.customStyle[`${row}-${col}`], 'color': color }
        }
    }

    sheetListRefs[sheetCode.value].hotInstance.render();
};

let backColorPicker = ref("#FFFFFF");

const editBackColor = (color: string) => {
    console.log(color);
    backColorPicker.value = color

    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    const table = hotTableList.filter((item: any) => item.key === sheetCode.value)[0]

    for (let row = startRow; row <= endRow; row++) {
        for (let col = startCol; col <= endCol; col++) {
            table.customStyle[`${row}-${col}`] = { ...table.customStyle[`${row}-${col}`], 'background': color }
        }
    }

    sheetListRefs[sheetCode.value].hotInstance.render();
};
const cellMenu = [
    { label: '加粗', key: '加粗' },
    { label: '斜体', key: '斜体' },
    { label: '下划线', key: '下划线' },
    { label: '中划线', key: '中划线' },
    { label: '字号+', key: '字号+' },
    { label: '字号-', key: '字号-' },
    { label: '文本高亮', key: '文本高亮' },
    { label: '背景高亮', key: '背景高亮' },
    {
        key: 'hivider',
        type: 'divider'
    },
    { label: '恢复默认', key: '恢复默认' }
]

const cellMenuSelect = (key: string) => {
    console.log(selected)
    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    let cell = sheetListRefs[sheetCode.value].hotInstance.getSettings().cell

    for (let row = startRow; row <= endRow; row++) {
        for (let col = startCol; col <= endCol; col++) {
            // const oldClassName = sheetListRefs[sheetCode.value].hotInstance.getCellMeta(row, col).className || '';
            const currentCell = cell.filter((e: any) => e.row === row && e.col === col)
            let oldClassName = '';
            let className;
            if (currentCell && currentCell[0]) {
                oldClassName = currentCell[0].className || ''
            }
            switch (key) {
                case '文本高亮':
                    className = mergeOrDeleteString(oldClassName, 'beRed')
                    break;
                case '背景高亮':
                    className = mergeOrDeleteString(oldClassName, 'beBackgroundYellow')
                    break;
                case '加粗':
                    className = mergeOrDeleteString(oldClassName, 'beBold')
                    break;
                case '斜体':
                    className = mergeOrDeleteString(oldClassName, 'beItalic')
                    break;
                case '下划线':
                    if (oldClassName.includes('beAllLine')) {
                        // 如果现在又有下划线，又有中划线。则点击下划线后，需要变成只显示中划线
                        // 去掉全划线，改成中划线
                        oldClassName = deleteString(oldClassName, 'beAllLine')
                        className = mergeOrDeleteString(oldClassName, 'beLineThrough')
                        break;
                    } else if (oldClassName.includes('beLineThrough')) {
                        // 如果现在只有中划线，则改成全划线
                        oldClassName = deleteString(oldClassName, 'beLineThrough')
                        className = mergeOrDeleteString(oldClassName, 'beAllLine')
                        break;
                    }

                    className = mergeOrDeleteString(oldClassName, 'beUnderline')
                    break;
                case '中划线':
                    if (oldClassName.includes('beAllLine')) {
                        // 如果现在又有下划线，又有中划线。则点击中划线后，需要变成只显示下划线
                        // 去掉全划线，改成下划线
                        oldClassName = deleteString(oldClassName, 'beAllLine')
                        className = mergeOrDeleteString(oldClassName, 'beUnderline')
                        break;
                    } else if (oldClassName.includes('beUnderline')) {
                        // 如果现在只有下划线，则改成全划线
                        oldClassName = deleteString(oldClassName, 'beUnderline')
                        className = mergeOrDeleteString(oldClassName, 'beAllLine')
                        break;
                    }

                    className = mergeOrDeleteString(oldClassName, 'beLineThrough')
                    break;

                case '字号+':
                    className = changeFontSize(oldClassName, true)
                    break;
                case '字号-':
                    className = changeFontSize(oldClassName, false)
                    break;
                default:
                    className = ''
                    break;
            }

            cell = mergeCellSetting(cell, { row, col, className, backgroundColor: 'yellow' });
            // sheetListRefs[sheetCode.value].hotInstance.setCellMetaObject(row, col, {
            //     ...sheetListRefs[sheetCode.value].hotInstance.getCellMeta(row, col),
            //     ...meta
            // })
        }
    }

    updateTableSettings(sheetCode.value, { cell })

}

const deleteString = (original: string, newStr: string) => {
    const originalWords = original.split(' ');
    const newWords = newStr.split(' ');

    const wordSet = new Set(originalWords);

    for (const word of newWords) {
        if (wordSet.has(word)) {
            wordSet.delete(word);
        }
    }

    // 使用Array.from将Set转换为数组，并拼接成字符串  
    return Array.from(wordSet).join(' ');
}

const mergeOrDeleteString = (original: string, newStr: string) => {
    const originalWords = original.split(' ');
    const newWords = newStr.split(' ');

    const wordSet = new Set(originalWords);

    for (const word of newWords) {
        if (wordSet.has(word)) {
            wordSet.delete(word);
        } else {
            wordSet.add(word);
        }
    }

    // 使用Array.from将Set转换为数组，并拼接成字符串  
    return Array.from(wordSet).join(' ');
}

const changeFontSize = (oldClassName: string, increase: boolean) => {
    // 定义一个正则表达式来匹配beFontSize-xx格式的类名  
    const fontSizeRegex = /beFontSize-(\d+)/;
    // 使用正则表达式查找匹配项  
    const match = oldClassName.match(fontSizeRegex);

    let className
    let newSize;
    if (match) {
        // 如果找到了匹配的类名，提取当前的字体大小数字  
        const currentSize = parseInt(match[1], 10);
        // 根据increase参数增加或减少字体大小，并确保大小在8到22之间  
        newSize = Math.min(22, Math.max(8, currentSize + (increase ? 1 : -1)));
        // 替换原有的beFontSize-xx类名为新的大小  
        className = oldClassName.replace(fontSizeRegex, 'beFontSize-' + newSize);
    } else {
        // 如果没有找到匹配的类名，则添加beFontSize-14（或根据需求调整）  
        newSize = increase ? 14 : 12; // 假设减小字体时直接设置为最小8  
        // 检查是否已经有一个beFontSize-xx类名（虽然按逻辑这里不应该有）  
        // 如果有的话，我们还是要替换它，以防万一  
        className = oldClassName.replace(fontSizeRegex, '').trim() + ' beFontSize-' + newSize;
    }

    return className;
}

const formatMenu = [
    { label: '居左', key: '居左' },
    { label: '居右', key: '居右' },
    { label: '水平居中', key: '水平居中' },
    { label: '居上', key: '居上' },
    { label: '居下', key: '居下' },
    { label: '垂直居中', key: '垂直居中' },
    {
        key: 'hivider',
        type: 'divider'
    },
    { label: '恢复默认', key: '恢复默认' }
]

const formatMenuSelect = (key: string) => {
    console.log(selected)
    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    let cell = sheetListRefs[sheetCode.value].hotInstance.getSettings().cell

    for (let row = startRow; row <= endRow; row++) {
        for (let col = startCol; col <= endCol; col++) {
            // const oldClassName = sheetListRefs[sheetCode.value].hotInstance.getCellMeta(row, col).className || '';
            const currentCell = cell.filter((e: any) => e.row === row && e.col === col)
            let oldClassName = '';
            if (currentCell && currentCell[0]) {
                oldClassName = currentCell[0].className || ''
            }
            let className;
            switch (key) {
                case '居右':
                    className = updateFormatClassName(oldClassName, 'htRight')
                    break;
                case '居左':
                    className = updateFormatClassName(oldClassName, 'htLeft')
                    break;
                case '水平居中':
                    className = updateFormatClassName(oldClassName, 'htCenter')
                    break;
                case '居上':
                    className = updateFormatClassName(oldClassName, 'htTop')
                    break;
                case '居下':
                    className = updateFormatClassName(oldClassName, 'htBottom')
                    break;
                case '垂直居中':
                    className = updateFormatClassName(oldClassName, 'htMiddle')
                    break;
                default:
                    className = ''
                    break;
            }

            cell = mergeCellSetting(cell, { row, col, className });
            // sheetListRefs[sheetCode.value].hotInstance.setCellMetaObject(row, col, {
            //     ...sheetListRefs[sheetCode.value].hotInstance.getCellMeta(row, col),
            //     className
            // })
        }
    }
    updateTableSettings(sheetCode.value, { cell })
}
/**
 * CSS class name 设置:
 * className="htRight htBottom"字符串，或形如className="htRight"，即有多个classname的时候，在字符串里是空格分隔的。
 * 已知htRight htLeft htCenter互斥，htTop htBottom htMiddle互斥，互斥的字符串同时只能存在一个。
 * 要给className赋值时，如想要赋值htCenter，如果className="htRight"那么赋值后，className应该是className="htCenter"；
 * 如果className="htMiddle"那么赋值后，className应该是className="htMiddle htCenter"；
 * 如果className="htMiddle htRight"那么赋值后，className应该是className="htMiddle htCenter"
 * 如果className=""（允许为空）那么赋值后，className应该是className="htCenter"；
 */
const updateFormatClassName = (existingClassName: string | undefined, newClassName: string) => {
    // 定义互斥类名组  
    const horizontalClasses = ['htRight', 'htLeft', 'htCenter'];
    const verticalClasses = ['htTop', 'htBottom', 'htMiddle'];

    // 检查当前 className 是否为空  
    if (!existingClassName || existingClassName.trim() === '') {
        return newClassName;
    }

    // 将 className 拆分为数组  
    const classes = existingClassName.split(' ');

    // 处理水平类名互斥  
    if (horizontalClasses.includes(newClassName)) {
        classes.filter(cls => horizontalClasses.includes(cls)).forEach(cls => {
            const index = classes.indexOf(cls);
            if (index > -1) {
                classes.splice(index, 1);
            }
        });
    }

    // 处理垂直类名互斥  
    if (verticalClasses.includes(newClassName)) {
        classes.filter(cls => verticalClasses.includes(cls)).forEach(cls => {
            const index = classes.indexOf(cls);
            if (index > -1) {
                classes.splice(index, 1);
            }
        });
    }

    // 添加新的类名  
    if (!classes.includes(newClassName)) {
        classes.push(newClassName);
    }

    // 拼接回 className 字符串  
    return classes.join(' ');
}

const placeMenu = [
    { label: '列宽增加', key: '列宽增加' },
    { label: '列宽减少', key: '列宽减少' },
    { label: '行高增加', key: '行高增加' },
    { label: '行高减少', key: '行高减少' },
]

const placeMenuSelect = (key: string) => {
    console.log(selected)
    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    const countCols = sheetListRefs[sheetCode.value].hotInstance.countCols();// 获取列数  
    // 创建一个数组来存储所有列的宽度  
    const colWidths = [];
    // 遍历所有列，获取每列的宽度  
    for (let i = 0; i < countCols; i++) {
        colWidths.push(sheetListRefs[sheetCode.value].hotInstance.getColWidth(i));
    }

    const countRows = sheetListRefs[sheetCode.value].hotInstance.countRows();// 获取行数  
    // 创建一个数组来存储所有行的高度  
    const rowHeights = [];

    // 遍历所有行，获取每行的高度  
    for (let i = 0; i < countRows; i++) {
        rowHeights.push(sheetListRefs[sheetCode.value].hotInstance.getRowHeight(i));
    }

    console.log(colWidths, rowHeights)
    console.log(sheetListRefs[sheetCode.value].hotInstance)

    switch (key) {
        case '列宽增加':
            // 对所有的选定列，都设置
            for (let col = startCol; col <= endCol; col++) {
                colWidths[col] = colWidths[col] + 50
            }
            // sheetListRefs[sheetCode.value].hotInstance.updateSettings({ colWidths })
            updateTableSettings(sheetCode.value, { colWidths })
            break;
        case '列宽减少':
            // 对所有的选定列，都设置
            for (let col = startCol; col <= endCol; col++) {
                colWidths[col] = colWidths[col] - 50 > 50 ? colWidths[col] - 50 : 50
            }
            // sheetListRefs[sheetCode.value].hotInstance.updateSettings({ colWidths })
            updateTableSettings(sheetCode.value, { colWidths })
            break;

        case '行高增加':
            // 对所有的选定行，都设置
            for (let row = startRow; row <= endRow; row++) {
                rowHeights[row] = rowHeights[row] + 10
            }
            // sheetListRefs[sheetCode.value].hotInstance.updateSettings({ rowHeights })
            updateTableSettings(sheetCode.value, { rowHeights })
            break;
        case '行高减少':
            // 对所有的选定行，都设置
            for (let row = startRow; row <= endRow; row++) {
                rowHeights[row] = rowHeights[row] - 10 > 10 ? rowHeights[row] - 10 : 10
            }
            // sheetListRefs[sheetCode.value].hotInstance.updateSettings({ rowHeights })
            updateTableSettings(sheetCode.value, { rowHeights })
            break;

        default:
            break;
    }
}

let dataarry = ref<string[][] | any[][]>([])

function saveExcel(){ 
    const saveTables = hotTableList.map((table:any) => {
        const data = table.data.map((row:any) => row.map((element:string) => encodeString(element)))
        return {
            ...table,
            data
        }
    }
   )

  let data = {
            类型: "数据",
            内容: {
                应用名称: props.currentApp['名称'],
                类型: "excel",
                名称: inputFileName.value,
                内容: saveTables
            }
        }
        console.log('提交的数据', data)
        FORM_ADD({ "params": JSON.stringify(data) }).then((res: any) => {
            // console.log( res);
            if (res.stacode == 200) {
                console.log(res)
                message.success('保存已提交')
            }
        }).catch((err: any) => {
            console.log('err', err);
        })
}

//设置单元格的数据类型
const setCellType = () => {
    console.log('设置单元格类型')
    // handsontable.value.setCellMetaObject(1, 2, { "type": "date", "format": "YYYY-MM-DD" })
    // handsontable.value.setCellMetaObject(1, 3, { "type": "numeric", "format": "0.00" })
    // handsontable.value.setCellMetaObject(1, 4, { "type": "dropdown", "source": ["A", "B", "C"] })
    // handsontable.value.setCellMetaObject(1, 5, { "type": "checkbox" })
    // handsontable.value.setCellMetaObject(1, 6, { "type": "autocomplete", "source": ["A", "B", "C"] })
    // handsontable.value.setCellMetaObject(1, 0, { "type": "password" })
    // handsontable.value.setCellMetaObject(1, 1, { "type": "text" })

}

/**
 * 定义单元格渲染器
 * 采用api对象的方式，绑定handsontable组件对象
 */

const exce = ref<HTMLDivElement | any>(null)
const initialize = () => {
    // handsontable.value = new Handsontable(exce.value, {
    //     data: exceldata.data,
    //     columns: columstype,
    //     cell: readOnlyCells,
    //     contextMenu: true,
    //     licenseKey: 'non-commercial-and-evaluation',
    //     width: '100%',
    //     rowHeaders: true,
    //     colHeaders: true,
    //     autoWrapRow: true,
    //     autoWrapCol: true,
    //     dropdownMenu: true,
    //     mergeCells: true,
    //     stretchH: 'all',
    //     language: 'zh-CN',
    // })
    // console.log(df)
}

/**
 * 头部标题图标设置
 * 头标下拉菜单设置
 */
const options_excel = [
    { label: '保存', key: '保存' },
    { label: '导入csv', key: '导入csv' },
    { label: '导出csv', key: '导出csv' },
    { label: '打印', key: '打印' }
]
const excelSelect = (key: string) => {
    console.log(key)
    if (key === "保存") {
    saveExcel()
  }
}
let excelIcon = () => {
    return h(NFlex, () => [
        h(NDropdown, { trigger: "hover", size: "huge", showArrow: true, options: options_excel, onSelect: excelSelect }, () => h(NButton, { text: true, style: 'font-size: 24px' }, () => h(SvgIcon, { iconClass: props.icon }))), 
        h('div', props.title),
        h("div", { style: "display: flex; align-items: center;font-size: 14px; margin-left: 30px; " }, [
      h('div', { style: "color: green;" }, '文件名：'),
      editFileNameMode.value ? undefined : h(SvgIcon, { iconClass: 'bianji', style:"font-size: 26px;", onClick: () => { editFileNameMode.value = true } }, ),
      h("div", { style: "min-width: 210px" },
        editFileNameMode.value ? h(NInput, {
          placeholder: '文件未命名',
          size: 'small',
          style: 'height: 28px; width: 200px;',
          maxlength: 30,
          showCount: true,
          // 注意：v-model 在渲染函数中需要拆分为 value 属性和 onInput 事件监听器  
          value: inputFileName.value, // 假设 inputFileName 是组件的 data 属性  
          onInput: (event) => { inputFileName.value = event },
          onBlur: () => { editFileNameMode.value = false }
        },) : h('div', { style: inputFileName.value ? "" : "color:lightgray", onClick: () => { editFileNameMode.value = true } }, inputFileName.value || "文件未命名")
      )]),
    ,
    autoSaveHappened.value ? h(NTag, { type: "success", bordered: false }, () => "已自动提交保存") :
    h(NTag, { type: "warning", bordered: false}, () => "文件会每一分钟自动提交保存"),
    h("div", { style: "font-size: 12px; display: flex; align-items: center; color:gray" },
      [
        h('div', { style: "" }, '下次自动保存：'),
        h(NCountdown, { duration: AUTO_SAVE_TIME, ref:countdownRef }),
      ]),
    ])
}
const header_excel = () => excelIcon()

/**
 * end
 */


/**
 * excel 控件菜单
 */
const controlMenu = [
    { label: '单选', key: '单选' },
    { label: '下拉', key: '下拉' },
    { label: '日期', key: '日期' },
    {
        key: 'hivider',
        type: 'divider'
    },
    { label: '恢复默认', key: '默认' },
]
const controlMenuSelect = (key: string) => {
    if (!selected) {
        return
    }

    let typeObj = {}
    switch (key) {
        case '日期':
            typeObj = { "type": "date", "format": "YYYY-MM-DD" }
            break;
        case '单选':
            typeObj = { "type": "checkbox" }
            break;
        case '下拉':
            typeObj = { "type": "dropdown", 'source': ['A', 'B', 'C'] }
            break;
        default:
            typeObj = { "type": "text" }
            break;
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    // for (let row = startRow; row <= endRow; row++) {
    //     for (let col = startCol; col <= endCol; col++) {
    //         sheetListRefs[sheetCode.value].hotInstance.setCellMetaObject(row, col, typeObj)
    //     }
    // }

    let cell = sheetListRefs[sheetCode.value].hotInstance.getSettings().cell
    for (let row = startRow; row <= endRow; row++) {
        for (let col = startCol; col <= endCol; col++) {
            cell = mergeCellSetting(cell, { row, col, ...typeObj });
        }
    }
    updateTableSettings(sheetCode.value, { cell })
}
/**
 * end
 * 
 */

/**
 * 根据选定的单元格，初始化图表数据
 */
const generateChartData = (startRow: number, startCol: number, endRow: number, endCol: number) => {
    const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    const colors = [
        '#dd6b66',
        '#759aa0',
        '#e69d87',
        '#8dc1a9',
        '#ea7e53',
        '#eedd78',
        '#73a373',
        '#73b9bc',
        '#7289ab',
        '#91ca8c',
        '#f49f42'
    ];

    const dataX = [];
    for (let i = startCol; i <= endCol; i++) {
        dataX.push(alphabet.charAt(i));
    }

    const series = [];
    for (let row = startRow; row <= endRow; row++) {
        const seriesItem: {
            color?: string,
            data: any[],
            type?: string; // 可选属性  
            stack: string;
            smooth?: boolean;
        } = {
            color: colors[(row - startRow) % colors.length],
            stack: 'x',
            data: []
        };

        for (let col = startCol; col <= endCol; col++) {
            const cellValue = sheetListRefs[sheetCode.value].hotInstance.getDataAtCell(row, col) as number;
            seriesItem.data.push({
                value: cellValue,
                name: getCharFromCode(col) + (row + 1),
            });
        }

        series.push(seriesItem);
    }

    return { dataX, series };
}
/**
 * 图表菜单
 */
const chartMenu = [
    { label: '柱状图', key: '柱状图' },
    { label: '折线图', key: '折线图' },
    { label: '饼图', key: '饼图' },
    { label: '散点图', key: '散点图' },
    // { label: '雷达图', key: '雷达图' },
    // { label: '热力图', key: '热力图' },
    // { label: '仪表图', key: '仪表图' },
    // { label: '箱线图', key: '箱线图' },
    // { label: '地图', key: '地图' },
    // { label: '自定义图表', key: '自定义图表' }
]
const chartMenuSelect = (key: string) => {
    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    const table = hotTableList.filter((item: any) => item.key === sheetCode.value)[0]
    table.showEcharts = true
    const eDomId = table.echarts;

    const chart = echarts.init(document.getElementById(eDomId))

    let { dataX, series } = generateChartData(startRow, startCol, endRow, endCol);
    switch (key) {
        case '柱状图':
            series.forEach(s => s.type = 'bar')
            break;
        case '折线图':
            series.forEach(s => s.type = 'line')
            series.forEach(s => s.smooth = true)
            break;
        case '散点图':
            series.forEach(s => s.type = 'scatter')
            break;
        case '饼图':
            dataX = []
            series.forEach(s => s.type = 'pie')
            series.forEach(s => s.color = undefined)
            break;
        default:
            break;
    }
    // 初始化chart
    chart.clear()
    // 使用新的方式设置chart
    const echartsOption = {
        title: {
            text: key
        },
        xAxis: {
            data: dataX
        },
        yAxis: {},
        series
    }
    chart.setOption(echartsOption)
    table.echartsOption = echartsOption

}
const handleCloseCard = () => {
    console.log('关闭Echarts卡片')
    const table = hotTableList.filter((item: any) => item.key === sheetCode.value)[0]
    table.showEcharts = false
}
/**
 * end
 */

/**
* 公式菜单
*/
const formulaMenu = [
    { label: '求和', key: 'sum' },
    { label: '平均值', key: 'ave' },
    { label: '最大值', key: 'max' },
    { label: '最小值', key: 'min' },
    { label: '计数', key: 'count' },
]
const formulaMenuSelect = (key: string) => {

    if (!selected) {
        return
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    const startCellName = getCharFromCode(startCol) + (startRow + 1)
    const endCellName = getCharFromCode(endCol) + (endRow + 1)

    let setRow = endRow + 1
    let setCol = endCol
    if (startRow === endRow && startCol !== endCol) { // 仅仅选了一长行
        setRow = endRow
        setCol = endCol + 1
    }

    switch (key) {
        case 'sum':
            sheetListRefs[sheetCode.value].hotInstance.setDataAtCell(setRow, setCol, `=SUM(${startCellName}:${endCellName})`)
            break;
        case 'ave':
            sheetListRefs[sheetCode.value].hotInstance.setDataAtCell(setRow, setCol, `=AVERAGE(${startCellName}:${endCellName})`)
            break;
        case 'min':
            sheetListRefs[sheetCode.value].hotInstance.setDataAtCell(setRow, setCol, `=MIN(${startCellName}:${endCellName})`)
            break;
        case 'max':
            sheetListRefs[sheetCode.value].hotInstance.setDataAtCell(setRow, setCol, `=MAX(${startCellName}:${endCellName})`)
            break;
        case 'count':
            sheetListRefs[sheetCode.value].hotInstance.setDataAtCell(setRow, setCol, `=COUNT(${startCellName}:${endCellName})`)
            break;
        default:
            break;
    }
}
/**
 * end
 */

/**
* 生成单元格名称，如 A1 C3 等
*/
const getCharFromCode = (c: number) => {
    // 确保c是一个非负整数，并且限制在'A'到'Z'的范围内（0-25）  
    c = (c + 26) % 26; // 处理负数和非字母字符范围的值，使其循环到0-25之间  
    return String.fromCharCode(65 + c); // 'A'的ASCII码是65，所以65+c会得到'A'到'Z'之间的字符  
}

/**
 * 单元类型
 */
const unitMenu = [
    { label: '文本类型', key: '文本' },
    { label: '数字类型', key: '数字' },
    { label: '日期类型', key: '日期' },
]
const unitMenuSelect = (key: string) => {
    console.log(key)
    if (!selected) {
        return
    }

    let typeObj = {}
    switch (key) {
        case '日期':
            typeObj = { "type": "date", "format": "YYYY-MM-DD" }
            break;
        case '文本':
            typeObj = { "type": "text" }
            break;
        case '数字':
            typeObj = { "type": "numeric", "format": "0.00" }
            break;
        default:
            typeObj = {}
            break;
    }

    const startRow = selected[0][0]
    const startCol = selected[0][1]
    const endRow = selected[0][2]
    const endCol = selected[0][3]

    // 对所有的选定格，都设置对应类型
    let cell = sheetListRefs[sheetCode.value].hotInstance.getSettings().cell
    for (let row = startRow; row <= endRow; row++) {
        for (let col = startCol; col <= endCol; col++) {
            cell = mergeCellSetting(cell, { row, col, ...typeObj });
        }
    }
    updateTableSettings(sheetCode.value, { cell })
}
/**
 * end
 */

/**
 * 关闭页面，返回路由上一页
 */

const handleClose = () => {
    console.log('关闭页面')
    router.go(-1)
}
/**
 * end
 */



</script>
<template>
    <n-card :title="header_excel" closable @close="handleClose">
        <template #header-extra>
            <n-flex justify="space-between">
                <slot name="header-extra"></slot>
                <n-button size="small" type="info" @click="saveExcel" ghost>保存</n-button>
            </n-flex>
        </template>

        <template #default>

            <n-flex vertical :size="[1, 0]">
                <!-- 插槽 -->
                <slot></slot>
                <!-- 操作按钮 -->
                <n-flex justify="space-between">
                    <!-- 左侧操作按钮 -->
                    <n-flex>
                    </n-flex>
                    <!-- 中间操作按钮 -->
                    <n-flex justify="left">
                        <n-dropdown trigger="hover" :options="controlMenu" @select="controlMenuSelect">
                            <n-button @click="select">控件</n-button>
                        </n-dropdown>
                        <n-dropdown trigger="hover" :options="unitMenu" @select="unitMenuSelect">
                            <n-button @click="setCellType">单元格类型</n-button>
                        </n-dropdown>
                        <n-dropdown trigger="hover" :options="insertMenu" @select="insertMenuSelect">
                            <n-button>插入</n-button>
                        </n-dropdown>
                        <n-dropdown trigger="hover" :options="deleteMenu" @select="deleteMenuSelect">
                            <n-button>删除</n-button>
                        </n-dropdown>
                        <n-button @click="mergeCellsClick">合并单元格</n-button>
                        <n-button @click="readOnlyCellsClick">设置单元格只读</n-button>
                        <n-dropdown trigger="hover" :options="formulaMenu" @select="formulaMenuSelect">
                            <n-button>公式</n-button>
                        </n-dropdown>
                        <n-dropdown trigger="hover" :options="chartMenu" @select="chartMenuSelect">
                            <n-button>图表</n-button>
                        </n-dropdown>
                    </n-flex>
                    <!-- 右侧操作按钮 -->
                    <n-flex justify="space-between">
                        <n-flex justify="end">
                            <!-- <n-dropdown trigger="hover" :options="cellMenu" @select="cellMenuSelect">
                            <n-button>单元格内容</n-button>
                        </n-dropdown>
                        <n-dropdown trigger="hover" :options="formatMenu" @select="formatMenuSelect">
                            <n-button>内容对齐</n-button>
                        </n-dropdown>
                        <n-dropdown trigger="hover" :options="borderMenu" @select="borderMenuSelect">
                            <n-button>边框</n-button>
                        </n-dropdown>
                            <n-dropdown trigger="hover" :options="placeMenu" @select="placeMenuSelect">
                                <n-button>排列</n-button>
                            </n-dropdown>-->
                            <n-button class="btntools" text @click="showPlane">
                                <template #icon>
                                    <n-icon>
                                        <svg-icon :icon-class="rightPlane ? 'chaboxiaoxi-yangshi' : 'yangshi'" />
                                    </n-icon>
                                </template>
                            </n-button>
                        </n-flex>
                    </n-flex>
                    <!-- 右侧操作按钮end -->
                </n-flex>
                <!-- 表格 -->
                <n-flex :size="[1, 0]">
                    <n-tabs :style="rightPlane ? 'width: calc(100vw - 330px);' : 'width: 100vw'" key="bar-bottom"
                        placement="bottom" type="line" animated addable default-value="sheet1"
                        :on-update:value="handleTabChange">
                        <template v-for="item in hotTableList" :key="item.key">
                            <n-tab-pane :name="item.key" :tab="item.key"
                                style="height: calc(100vh - 264px); overflow-y: auto;">
                                <hot-table :ref="setItemRef(item.key)" :settings="item.setting" :data="item.data"
                                    v-if="!excelTableLoading"></hot-table>
                                <n-card v-show="item.showEcharts" closable @close="handleCloseCard">
                                    <div :id="item.echarts" style="width: 75vw; height: 400px"></div>
                                </n-card>
                            </n-tab-pane>
                        </template>
                    </n-tabs>

                    <!-- 右侧栏 -->
                    <n-card v-show="rightPlane" style="width: 250px;">
                        <n-tabs placement="top" animated default-value="a">
                            <n-tab-pane name="a" tab="单元格">
                                <n-flex vertical>
                                    <div class="my-title">边框</div>
                                    <n-space>
                                        <n-button-group size="small">
                                            <n-button type="default" round @click="borderMenuSelect('外侧边框')">
                                                加边框
                                            </n-button>
                                            <n-button type="default" round @click="borderMenuSelect('无边框')">
                                                去边框
                                            </n-button>
                                        </n-button-group>
                                    </n-space>
                                    <n-flex justify="space-between">
                                        <span>&nbsp;&nbsp;边框颜色&nbsp;&nbsp;
                                            <n-color-picker :show-alpha="false" :modes="['hex']"
                                                v-model:value="borderColorPicker"
                                                :on-update:value="editBorderColor" /></span>
                                    </n-flex>

                                    <n-flex justify="space-between">
                                        <div class="my-title">填充颜色</div>
                                        <n-color-picker v-model:value="backColorPicker" :show-alpha="false"
                                            :modes="['hex']" :on-update:value="editBackColor" />
                                    </n-flex>
                                </n-flex>
                            </n-tab-pane>
                            <n-tab-pane name="b" tab="文本">
                                <n-flex vertical>
                                    <div class="my-title">字体</div>
                                    <n-space>
                                        <n-button-group size="small">
                                            <n-button type="default" round @click="cellMenuSelect('加粗')">
                                                <template #icon>
                                                    <n-icon>
                                                        <SvgIcon iconClass="zitijiacu" />
                                                    </n-icon>
                                                </template>
                                            </n-button>
                                            <n-button type="default" @click="cellMenuSelect('斜体')">
                                                <template #icon>
                                                    <n-icon>
                                                        <SvgIcon iconClass="zitixieti" />
                                                    </n-icon>
                                                </template>
                                            </n-button>
                                            <n-button type="default" @click="cellMenuSelect('下划线')">
                                                <template #icon>
                                                    <n-icon>
                                                        <SvgIcon iconClass="zitixiahuaxian" />
                                                    </n-icon>
                                                </template>
                                            </n-button>
                                            <n-button type="default" round @click="cellMenuSelect('中划线')">
                                                <template #icon>
                                                    <n-icon>
                                                        <SvgIcon iconClass="a-bianzu3" />
                                                    </n-icon>
                                                </template>
                                            </n-button>
                                        </n-button-group>
                                    </n-space>
                                    <n-space>
                                        <n-button-group size="small">
                                            <n-button type="default" round @click="formatMenuSelect('居左')">
                                                <template #icon>
                                                    <n-icon>
                                                        <SvgIcon iconClass="zuoduiqi" />
                                                    </n-icon>
                                                </template>
                                            </n-button>
                                            <n-button type="default" @click="formatMenuSelect('水平居中')">
                                                <template #icon>
                                                    <n-icon>
                                                        <SvgIcon iconClass="juzhongduiqi" />
                                                    </n-icon>
                                                </template>
                                            </n-button>
                                            <n-button type="default" round @click="formatMenuSelect('居右')">
                                                <template #icon>
                                                    <n-icon>
                                                        <SvgIcon iconClass="youduiqi" />
                                                    </n-icon>
                                                </template>
                                            </n-button>
                                        </n-button-group>
                                    </n-space>
                                    <n-space>
                                        <n-button-group size="small">
                                            <n-button type="default" round @click="formatMenuSelect('居上')">
                                                居上
                                            </n-button>
                                            <n-button type="default" @click="formatMenuSelect('垂直居中')">
                                                垂直居中
                                            </n-button>
                                            <n-button type="default" round @click="formatMenuSelect('居下')">
                                                居下
                                            </n-button>
                                        </n-button-group>
                                    </n-space>
                                    <n-space>
                                        <n-button-group size="small">
                                            <n-button type="default" round @click="cellMenuSelect('字号+')">
                                                <template #icon>
                                                    <n-icon>
                                                        <SvgIcon iconClass="zitishangbiao" />
                                                    </n-icon>
                                                </template>
                                            </n-button>
                                            <n-button type="default" round @click="cellMenuSelect('字号-')">
                                                <template #icon>
                                                    <n-icon>
                                                        <SvgIcon iconClass="zitixiabiao" />
                                                    </n-icon>
                                                </template>
                                            </n-button>
                                        </n-button-group>
                                    </n-space>
                                    <n-flex justify="space-between">
                                        <div class="my-title">文本颜色</div>
                                        <n-color-picker :show-alpha="false" :modes="['hex']"
                                            :on-update:value="editTextColor" />
                                    </n-flex>
                                </n-flex>
                            </n-tab-pane>
                            <n-tab-pane name="c" tab="排列">
                                <n-flex vertical>
                                    <div class="my-title">行列</div>
                                    <n-space>
                                        <n-button-group size="small">
                                            <n-button type="default" round @click="placeMenuSelect('列宽增加')">
                                                列宽+
                                            </n-button>
                                            <n-button type="default" round @click="placeMenuSelect('列宽减少')">
                                                列宽-
                                            </n-button>
                                        </n-button-group>
                                        <n-button-group size="small">
                                            <n-button type="default" round @click="placeMenuSelect('行高增加')">
                                                行高+
                                            </n-button>
                                            <n-button type="default" round @click="placeMenuSelect('行高减少')">
                                                行高-
                                            </n-button>
                                        </n-button-group>
                                    </n-space>
                                </n-flex>
                            </n-tab-pane>
                        </n-tabs>
                    </n-card>
                </n-flex>
            </n-flex>
        </template>

        <template #footer>
            <slot name="footer"></slot>
        </template>
        <template #action>
            <slot name="action"></slot>
        </template>
    </n-card>

</template>
<style>
.beRed {
    color: red;
}

.beBold {
    font-weight: bold;
}

.beItalic {
    font-style: italic;
}

/* 下划线 */
.beUnderline {
    text-decoration: underline;
}

.beLineThrough {
    text-decoration: line-through;
}

.beAllLine {
    text-decoration: underline line-through;
}

.beBackgroundYellow {
    background-color: yellow !important;
}

.beFontSize-8 {
    font-size: 8px;
}

.beFontSize-9 {
    font-size: 9px;
}

.beFontSize-10 {
    font-size: 10px;
}

.beFontSize-11 {
    font-size: 11px;
}

.beFontSize-12 {
    font-size: 12px;
}

.beFontSize-13 {
    font-size: 13px;
}

.beFontSize-14 {
    font-size: 14px;
}

.beFontSize-15 {
    font-size: 15px;
}

.beFontSize-16 {
    font-size: 16px;
}

.beFontSize-17 {
    font-size: 17px;
}

.beFontSize-18 {
    font-size: 18px;
}

.beFontSize-19 {
    font-size: 19px;
}

.beFontSize-20 {
    font-size: 20px;
}

.beFontSize-21 {
    font-size: 21px;
}

.beFontSize-22 {
    font-size: 22px;
}

.btntools {
    font-size: 24px;
    margin-left: 5px;
    margin-right: 10px;
}
</style>